#pragma once

#include "kernel/interfaces/ILogger.h"
#include <QPointF>
#include <QString>
#include <QHash>
#include <vector>
#include <string>
#include <memory>

namespace application {

class MapApplicationService;

namespace simulation {

/**
 * @brief 物理模拟器 - 模拟AGV运动行为
 * @details 根据路径指令模拟车辆沿站点移动，输出位置、速度、朝向
 */
class PhysicsSimulator {
public:
    /**
     * @brief 车辆状态
     */
    struct VehicleState {
        int agvNumber;
        QPointF position;              // 当前位置(m)
        double heading;                // 朝向(弧度)
        double velocity;               // 速度(m/s)
        double acceleration;           // 加速度(m/s²)
        std::vector<std::string> pathStations;  // 待执行路径
        size_t currentSegmentIndex;    // 当前段索引
        QString currentMap;            // 当前地图
        bool isPaused;                 // 是否暂停
        QString lastStation;           // 最近的站点（空路径时用于保持当前位置）
        double batteryLevelPercent;    // 电量百分比 [0, 100]
        bool charging;                 // 是否处于充电状态

        VehicleState()
            : agvNumber(0)
            , heading(0.0)
            , velocity(0.0)
            , acceleration(0.0)
            , currentSegmentIndex(0)
            , isPaused(false)
            , batteryLevelPercent(90.0)
            , charging(false)
        {}
    };

    explicit PhysicsSimulator(
        std::shared_ptr<MapApplicationService> mapService,
        std::shared_ptr<kernel::ILogger> logger
    );

    /**
     * @brief 更新车辆状态（时间步进）
     * @param agvNumber AGV编号
     * @param deltaTime 时间增量（秒）
     */
    void updateVehicle(int agvNumber, double deltaTime);

    /**
     * @brief 获取车辆状态
     */
    VehicleState getState(int agvNumber) const;

    /**
     * @brief 设置车辆路径
     * @param agvNumber AGV编号
     * @param stations 站点列表
     */
    void setPath(int agvNumber, const std::vector<std::string>& stations);

    /**
     * @brief 追加路径段
     * @param agvNumber AGV编号
     * @param stations 站点列表
     */
    void appendPath(int agvNumber, const std::vector<std::string>& stations);

    /**
     * @brief 暂停车辆
     */
    void pauseVehicle(int agvNumber);

    /**
     * @brief 恢复车辆
     */
    void resumeVehicle(int agvNumber);

    /**
     * @brief 取消车辆任务
     */
    void cancelVehicle(int agvNumber);

    /**
     * @brief 注册车辆
     * @param agvNumber AGV编号
     * @param initialStation 初始站点
     * @param mapName 初始地图
     * @param initialBatteryPercent 初始电量百分比（0-100）
     */
    void registerVehicle(int agvNumber,
                         const std::string& initialStation,
                         const std::string& mapName,
                         double initialBatteryPercent = 90.0);

    /**
     * @brief 注销车辆
     */
    void unregisterVehicle(int agvNumber);

    /**
     * @brief 设置车辆充电状态
     */
    void setCharging(int agvNumber, bool charging);

    /**
     * @brief 检查车辆是否存在
     */
    bool hasVehicle(int agvNumber) const;

    /**
     * @brief 设置最大速度
     */
    void setMaxSpeed(double speed) { m_maxSpeed = speed; }

    /**
     * @brief 设置到站阈值
     */
    void setArrivalThreshold(double threshold) { m_arrivalThreshold = threshold; }

private:
    std::shared_ptr<MapApplicationService> m_mapService;
    std::shared_ptr<kernel::ILogger> m_logger;

    QHash<int, VehicleState> m_vehicles;  // AGV编号 -> 状态

    // 物理参数
    double m_maxSpeed;           // 最大速度(m/s)
    double m_arrivalThreshold;   // 到站阈值(m)

    /**
     * @brief 获取站点坐标
     */
    QPointF getStationPosition(const QString& stationId, const QString& mapName);

    /**
     * @brief 获取车辆状态引用（可修改）
     */
    VehicleState* getVehicleState(int agvNumber);
};

} // namespace simulation
} // namespace application
